package com.yxw.bamboo.core;

import com.yxw.bamboo.core.send.event.SqlEventListener;
import com.yxw.bamboo.core.send.event.EventArgs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.Socket;
import java.net.SocketException;

//端口转发
public class NetPortForward implements Runnable {

    private final static Logger logger = LoggerFactory.getLogger(NetPortForward.class);
    private Socket host;
    private Socket remoteHost;
    private InputStream in;
    private OutputStream out;

    SqlEventListener beforeSqlEventListener;
    SqlEventListener afterSqlEventListener;

    public SocketChannel getChannel() {
        return channel;
    }

    private SocketChannel channel;
    NetPortForward(Socket host, Socket remoteHost, InputStream in, OutputStream out,
                   SocketChannel channel,SqlEventListener beforeSqlEventListener
            , SqlEventListener afterSqlEventListener) {
        this.host = host;
        this.remoteHost = remoteHost;
        this.in = in;
        this.out = out;
        this.channel=channel;
        this.beforeSqlEventListener=beforeSqlEventListener;
        this.afterSqlEventListener=afterSqlEventListener;
        //调用工厂自动创建listen
    }

    @Override
    public void run() {

        int length = 0;
        byte[] buffer = new byte[255 * 255*255];
        try {
            Socket inSocket=null;
            if(channel.getChannelName().equals(SocketChannel.LOCAL_TO_REMOTE))
            {
                 inSocket=host;
            }else
            {
                inSocket=remoteHost;
            }
            while (!inSocket.isClosed()&&!inSocket.isInputShutdown()
                    && (length = in.read(buffer)) > -1) {
               // clientList.put(host, new Date
                //
                //
                // ());
                byte[] des=new byte[length];
                this.channel.addSocketStep(1);
                System.arraycopy(buffer, 0, des, 0, length);

                EventArgs beforeEventArgs= new EventArgs(des);
                beforeSqlEventListener.trigger(this,beforeEventArgs);

                if(beforeEventArgs.getResult()!=null)
                {
                    byte[] newSendBytes=(byte[]) beforeEventArgs.getResult();
                    out.write(newSendBytes, 0,  newSendBytes.length);
                }else
                {
                    out.write(buffer, 0, des.length);
                }

                if(afterSqlEventListener!=null)
                {
                    afterSqlEventListener.trigger(this,new EventArgs(null));
                }

            }

            out.flush();

        } catch (SocketException se)
        {

        }
        catch (Exception e) {
            logger.error(channel.getChannelName()+host.hashCode()+"--error--"+e.getMessage());
        } finally {
            if(!host.isClosed())
            {
               NetHelper.close(host);;
            }
            if(!remoteHost.isClosed())
            {
                NetHelper.close(remoteHost);
            }

        }
    }
}
